package com.qinghe.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;

import com.qinghe.pro.exception.ServiceException;

public class FileUtils {

	public final static long ONE_KB = 1024;
	public final static long ONE_MB = ONE_KB * 1024;
	public final static long ONE_GB = ONE_MB * 1024;
	public final static long ONE_TB = ONE_GB * (long) 1024;
	public final static long ONE_PB = ONE_TB * (long) 1024;

	/**
	 * 得到文件大小
	 * 
	 * @param fileSize
	 * 
	 * @return String
	 */
	public static String getHumanReadableFileSize(long fileSize) {
		if (fileSize < 0) {
			return String.valueOf(fileSize);
		}
		String result = getHumanReadableFileSize(fileSize, ONE_PB, "PB");
		if (result != null) {
			return result;
		}

		result = getHumanReadableFileSize(fileSize, ONE_TB, "TB");
		if (result != null) {
			return result;
		}
		result = getHumanReadableFileSize(fileSize, ONE_GB, "GB");
		if (result != null) {
			return result;
		}
		result = getHumanReadableFileSize(fileSize, ONE_MB, "MB");
		if (result != null) {
			return result;
		}
		result = getHumanReadableFileSize(fileSize, ONE_KB, "KB");
		if (result != null) {
			return result;
		}
		return String.valueOf(fileSize) + "B";
	}

	private static String getHumanReadableFileSize(long fileSize, long unit,
			String unitName) {
		if (fileSize == 0)
			return "0";

		if (fileSize / unit >= 1) {
			double value = fileSize / (double) unit;
			DecimalFormat df = new DecimalFormat("######.##" + unitName);
			return df.format(value);
		}
		return null;
	}
	
	public static String getFileExt(String fileName) {
		if (fileName == null)
			return "";

		String ext = "";
		int lastIndex = fileName.lastIndexOf(".");
		if (lastIndex >= 0) {
			ext = fileName.substring(lastIndex + 1).toLowerCase();
		}

		return ext;
	}

	/**
	 * 得到不包含后缀的文件名字
	 * 
	 * @param name
	 * 
	 * @return String
	 */
	public static String getRealName(String name) {
		if (name == null) {
			return "";
		}

		int endIndex = name.lastIndexOf(".");
		if (endIndex == -1) {
			return null;
		}
		return name.substring(0, endIndex);
	}
	
	/**
	 * 取得真实路径
	 * 
	 * @param request HttpServletRequest
	 * 
	 * @return String
	 * 
	 */
	public static String getFileStorePath(HttpServletRequest request) {
		return request.getSession().getServletContext().getRealPath("/");
	}

	/**
	 * 取得根路径webRoot
	 * 
	 * @param request HttpServletRequest
	 * 
	 * @return String
	 */
	public static String getContextPath(HttpServletRequest request) {
		return request.getSession().getServletContext().getContextPath();
	}

	/**
	 * 文件流上传
	 * 
	 * @param ins
	 * @param path
	 * 
	 * @return
	 */
	public static void writeToFile(InputStream ins, String path) {
        try {
            OutputStream out = new FileOutputStream(new File(path));
            int read = 0;
            byte[] bytes = new byte[1024];

            while ((read = ins.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	
	/**
	 * 剪切文件到目标路径
	 * 
	 * @param request HttpServletRequest
	 * @param url 临时文件的相对路径，如：/temp/user-pic/20140322/201403221318490711.gif
	 * @param destPath 相对目标路径，如：/attachment/user-pic/20140322
	 * 
	 * @return
	 * @throws ServiceException
	 */
	public static void copyFile(HttpServletRequest request, String url, String destPath) {
		if (StringUtils.isBlank(url) || StringUtils.isBlank(destPath))
			return;
		String fileName = url.substring(url.lastIndexOf("/") + 1, url.length());
		String srcPath = url.substring(0, url.lastIndexOf("/"));
		
		if (srcPath.equals(destPath))// 如果源路径和目标路径相等
			return;
		
		File srcFile = new File(getFileStorePath(request) + srcPath.replace("/", File.separator), fileName);
		File destFile = new File(getFileStorePath(request) + destPath.replace("/", File.separator), fileName);
		
		if (srcFile.exists()) {
			try {
				org.apache.commons.io.FileUtils.moveFile(srcFile, destFile);
			} catch (IOException e) {
				throw new ServiceException("文件保存失败，请稍后再试。");
			}
		}
	}
	
	/**
	 * 删除文件
	 * 
	 * @param request HttpServletRequest
	 * @param url 文件的相对路径，如：/attachment/user-pic/20140322/201403221318490711.gif
	 * 
	 * @return
	 * @throws ServiceException
	 */
	public static void deleteFile(HttpServletRequest request, String url) {
		if (StringUtils.isBlank(url))
			return;
		String uploadPath = getFileStorePath(request) + url.replace("/", File.separator);
		File file = new File(uploadPath);
		
		if (file.exists()) {
			try {
				org.apache.commons.io.FileUtils.forceDelete(file);
			} catch (IOException e) {
				throw new ServiceException("文件删除失败，请稍后再试。");
			}
		}
	}
	
	/**
	 * 比较文件夹fileFolder和list的文件，删除文件夹中不存在于list中的文件
	 * 
	 * @param request HttpServletRequest
	 * @param fileFolder 文件夹url
	 * @param list 附件名称列表
	 * 
	 * @return
	 * @throws ServiceException
	 */
	public static void compareFile(HttpServletRequest request, String fileFolder,
			List<String> list) {
		String uploadPath = getFileStorePath(request) + fileFolder.replace("/", File.separator);
		File file = new File(uploadPath);
		
		if (file.exists()) {
			if (file.isDirectory()) {
				String files[] = file.list();
		        
		        for(int i = 0; i < files.length; i++) {
		        	if (!list.contains(files[i])) {
		            	try {
		    				org.apache.commons.io.FileUtils.forceDelete(new File(uploadPath + File.separator + files[i]));
		    			} catch (IOException e) {
		    				throw new ServiceException("文件删除失败，请稍后再试。");
		    			}
		        	}
		        }
			}
		}
	}
	
	/**
	 * 统计文件夹下的文件数量
	 * 
	 * @param request HttpServletRequest
	 * @param fileFolder 文件夹url
	 * 
	 * @return Integer
	 */
	public static Integer getFileNum(HttpServletRequest request, String fileFolder) {
		Integer num = 0;
		String uploadPath = getFileStorePath(request) + fileFolder.replace("/", File.separator);
		File file = new File(uploadPath);
		
		if (file.exists()) {
			if (file.isDirectory()) {
				String files[] = file.list();
				num = files.length;
			}
		}
        
        return num;
	}
	
}
